/*******************************************************************************
 *    系统名称   ：GMAgent服务系统
 *    公司      ： 成都欢娱乐互动
 *    文件名    ： MinaServer.java
 *              (C) Copyright joyct Corporation 2011
 *               All Rights Reserved.
 * *****************************************************************************
 *    注意： 本内容仅限于 成都欢娱乐互动公司内部使用，禁止转发
 ******************************************************************************/
package com.ricky.core.net;

import java.io.IOException;
import java.net.InetSocketAddress;

import org.apache.log4j.Logger;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

import com.ricky.core.net.abs.Request;
import com.ricky.core.net.abs.NetServer;
import com.ricky.core.net.msg.ByteContext;
import com.ricky.core.net.msg.Context;
import com.ricky.core.net.protocol.AMF3ProtocolCodecFactory;
import com.ricky.core.net.utils.Attributes;

/***
 *	MinaServer.java</br>
 *	@author pu
 *  @Data 2011-12-14</br>
 *	@version v0.1</br>
 *	@Discription 
 ***/
public class MinaServer extends NetServer implements IoHandler {

	protected static Logger log = Logger.getLogger(MinaServer.class);

	private IoAcceptor acceptor;
	
	/**
	 * @param port
	 * @param maxConnection
	 */
	public MinaServer(int port, int maxConnection) {
		super(port, maxConnection);
	}

	/* (non-Javadoc)
	 * @see com.ricky.core.net.abs.NetServer#init()
	 */
	@Override
	public void init() {
		acceptor = new NioSocketAcceptor();
		acceptor.getSessionConfig().setMaxReadBufferSize(2048);
		acceptor.getFilterChain().addLast("Logging", new LoggingFilter());
		acceptor.getFilterChain().addLast("codec",
				new ProtocolCodecFilter(new AMF3ProtocolCodecFactory()));
		acceptor.setHandler(this);

	}

	/* (non-Javadoc)
	 * @see com.ricky.core.net.abs.NetServer#start()
	 */
	@Override
	public void start() {
		try {
			acceptor.bind(new InetSocketAddress(port));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/* (non-Javadoc)
	 * @see org.apache.mina.core.service.IoHandler#exceptionCaught(org.apache.mina.core.session.IoSession, java.lang.Throwable)
	 */
	@Override
	public void exceptionCaught(IoSession arg0, Throwable arg1)
			throws Exception {
		log.error("minaServer.exceptionCaught", arg1);
	}

	/* (non-Javadoc)
	 * @see org.apache.mina.core.service.IoHandler#messageReceived(org.apache.mina.core.session.IoSession, java.lang.Object)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void messageReceived(IoSession session, Object data) throws Exception {
		if(data instanceof ByteContext)
		{
			session.write(data);
		}else
		{
			Context<?> context = (Context<?>) data;
			
			Request req = (Request) session
					.getAttribute(Attributes.CONN);
			if (req == null) {
				req = new MinaRequest(session);
				session.setAttribute(Attributes.CONN, req);
				iServerListener.onConnectionCreated(req);
			}
			
			if (!session.isClosing() && session.isConnected())
				iMessageListener.onMessageArrived(req,context);	
		}
	}

	/* (non-Javadoc)
	 * @see org.apache.mina.core.service.IoHandler#messageSent(org.apache.mina.core.session.IoSession, java.lang.Object)
	 */
	@Override
	public void messageSent(IoSession arg0, Object arg1) throws Exception {
//		log.info(arg0.getRemoteAddress()+"消息以发送:"+arg1);
	}

	/* (non-Javadoc)
	 * @see org.apache.mina.core.service.IoHandler#sessionClosed(org.apache.mina.core.session.IoSession)
	 */
	@Override
	public void sessionClosed(IoSession session) throws Exception {
		if (iServerListener != null) {
			Request conn = (Request) session
					.getAttribute(Attributes.CONN);
			if (conn != null ) {
				iServerListener.onConnectionClosed(conn);
			}
		}		
	}

	/* (non-Javadoc)
	 * @see org.apache.mina.core.service.IoHandler#sessionCreated(org.apache.mina.core.session.IoSession)
	 */
	@Override
	public void sessionCreated(IoSession session) throws Exception {
		session.setAttribute(Attributes.RECEIVE_MSG_COUNT, 0);
		if (iServerListener != null) {
			Request conn = new MinaRequest(session);
			session.setAttribute(Attributes.CONN, conn);
			iServerListener.onConnectionCreated(conn);
		}
		
	}

	/* (non-Javadoc)
	 * @see org.apache.mina.core.service.IoHandler#sessionIdle(org.apache.mina.core.session.IoSession, org.apache.mina.core.session.IdleStatus)
	 */
	@Override
	public void sessionIdle(IoSession arg0, IdleStatus arg1) throws Exception {
		
	}

	/* (non-Javadoc)
	 * @see org.apache.mina.core.service.IoHandler#sessionOpened(org.apache.mina.core.session.IoSession)
	 */
	@Override
	public void sessionOpened(IoSession session) throws Exception {
		log.info("有用户连接进来:"+session.getRemoteAddress());
		// 连接打开
		if (iServerListener != null) {
			Request conn = (Request) session
					.getAttribute(Attributes.CONN);
			if (conn != null ) {
				iServerListener.onConnectionOpend(conn);
			}
		}		
	}

}
